package org.tamal.classinfo;

import java.io.DataInputStream;
import java.io.IOException;

/**
 * This class represents verification_type_info structure that is part of
 * StackMapTable attribute of a class.
 *
 * @author Tamal Kanti Nath
 */
public final class VerificationType {
    /**
     * ITEM_Top (top).
     */
    public static final int ITEM_TOP = 0;
    /**
     * ITEM_Integer (int).
     */
    public static final int ITEM_INTEGER = 1;
    /**
     * ITEM_Float (float).
     */
    public static final int ITEM_FLOAT = 2;
    /**
     * ITEM_Double (double).
     */
    public static final int ITEM_DOUBLE = 3;
    /**
     * ITEM_Long (long).
     */
    public static final int ITEM_LONG = 4;
    /**
     * ITEM_Null (null).
     */
    public static final int ITEM_NULL = 5;
    /**
     * ITEM_UninitializedThis (uninitializedThis).
     */
    public static final int ITEM_THIS = 6;
    /**
     * ITEM_Object.
     */
    public static final int ITEM_OBJECT = 7;
    /**
     * ITEM_Uninitialized.
     */
    public static final int ITEM_UNINITIALIZED = 8;

    private final int tag;
    private Integer cpoolIndex;
    private Integer offset;

    /**
     * Creates Verification Type of a StackMapFrame.
     * @param in The DataInputStream
     * @throws IOException exception
     * @see StackMapFrame
     */
    VerificationType(DataInputStream in) throws IOException {
        tag = in.readUnsignedByte();
        switch (tag) {
        case ITEM_TOP:
        case ITEM_INTEGER:
        case ITEM_FLOAT:
        case ITEM_DOUBLE:
        case ITEM_LONG:
        case ITEM_NULL:
        case ITEM_THIS:
            break;
        case ITEM_OBJECT:
            cpoolIndex = in.readUnsignedShort();
            break;
        case ITEM_UNINITIALIZED:
            offset = in.readUnsignedShort();
            break;
        default:
            throw new ClassFormatException("Invalid Verification Type");
        }
    }

    /**
     * Returns Tag.
     * @return the tag
     */
    public int getTag() {
        return tag;
    }

    /**
     * Returns cpoolIndex.
     * @return the cpoolIndex
     */
    public Integer getCpoolIndex() {
        return cpoolIndex;
    }

    /**
     * Returns Offset.
     * @return the offset
     */
    public Integer getOffset() {
        return offset;
    }
}
